﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Objects.DataClasses;
using System.Data.Objects;
using Ovvio.Business;
using System.Linq.Expressions;

namespace Ovvio.Web.Core
{
    public class ModelProvider<TKey, TModel, TEntity, TObjectContext> : IModelProvider
        where TEntity : EntityObject, new() 
        where TObjectContext : ObjectContext, new()
        where TModel : BaseModel<TEntity>, new()
    {
        private Func<TModel, TKey> _predicate;
        protected ServiceBase<TKey, TEntity, TObjectContext> _service;

        public ServiceBase<TKey, TEntity, TObjectContext> Service { get { return _service; } }

        public ModelProvider(Func<TModel, TKey> modelPredicate, Expression<Func<TEntity, TKey>> entityPredicate, string entitySet, string paths)
            : this (modelPredicate, new ServiceBase<TKey,TEntity,TObjectContext>(entitySet, paths, entityPredicate))
        { }

        public ModelProvider(Func<TModel, TKey> predicate, ServiceBase<TKey, TEntity, TObjectContext> service)
        {
            _predicate = predicate;
            _service = service;
        }

        public IList<TModel> GetList()
        {
            var entities =  _service.GetEntities();
            var models = new List<TModel>();
            foreach (var entity in entities)
            {
                var newModel = new TModel();
                newModel.Entity = entity;
                models.Add(newModel);
            }
            return models;
        }

        public IList<TModel> GetList(Func<TEntity, bool> filterPredicate)
        {
            var entities = _service.GetEntities(filterPredicate);
            var models = new List<TModel>();
            foreach (var entity in entities)
            {
                var newModel = new TModel();
                newModel.Entity = entity;
                models.Add(newModel);
            }
            return models;
        }


        public TModel Get(TKey id)
        {
            var entity = _service.GetEntityByKey(id);
            if (entity != null)
            {
                var newModel = new TModel();
                newModel.Entity = entity;
                return newModel;
            }
            return new TModel();
        }

        public TModel Get(Func<TEntity, bool> filterPredicate)
        {
            var entity = _service.GetEntity(filterPredicate);
            if (entity != null)
            {
                var newModel = new TModel();
                newModel.Entity = entity;
                return newModel;
            }
            return new TModel();
        }

        public TModel Create()
        {
            return new TModel() { Entity = _service.Create() };
        }

        public virtual bool Save(TModel model)
        {
            return _service.Save(model.Entity, _predicate(model));
        }

        public bool Delete(TModel model)
        {
            return _service.Delete(model.Entity, _predicate(model));
        }

       
    }
}
